﻿using System;
using System.Runtime.InteropServices;

namespace SpiderMonkey
{
    internal static class Native
    {
        // ReSharper disable InconsistentNaming
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        internal delegate void JSErrorReporter(IntPtr cx, string message, IntPtr report);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        internal delegate int JSPropertyOp(IntPtr cx, IntPtr obj, IntPtr id, IntPtr vp);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        internal delegate int JSStrictPropertyOp(IntPtr cx, IntPtr obj, IntPtr id, int strict, IntPtr vp);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        internal delegate int JSEnumerateOp(IntPtr cx, IntPtr obj);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        internal delegate int JSResolveOp(IntPtr cx, IntPtr obj, ulong id);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        internal delegate int JSConvertOp(IntPtr cx, IntPtr obj, JSType type, IntPtr vp);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        internal delegate void JSFinalizeOp(IntPtr cx, IntPtr obj);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        internal delegate int JSNative(IntPtr cx, int argc, IntPtr vp);
        // ReSharper restore InconsistentNaming

        private const string SPIDERMONKEY = "mozjs185-1.0.dll";
        
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr JS_Init(uint maxbytes);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr JS_NewContext(IntPtr rt, int stackchunksize);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern uint JS_SetOptions(IntPtr cx, uint options);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern Version JS_SetVersion(IntPtr cx, Version version);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr JS_SetErrorReporter(IntPtr cx, IntPtr er);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern ulong OBJECT_TO_JSVAL(IntPtr pointer);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr JS_NewCompartmentAndGlobalObject(IntPtr cx, IntPtr clasp, IntPtr principals);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern int JS_InitStandardClasses(IntPtr cx, IntPtr obj);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr JS_GetClass(IntPtr obj);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern void JS_DestroyContext(IntPtr cx);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern void JS_Finish(IntPtr rt);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern void JS_ShutDown();
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern int JS_EvaluateScript(IntPtr cx, IntPtr obj, string src, uint length, string filename, int lineno, out ulong rval);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr JS_EncodeString(IntPtr cx, IntPtr str);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern int JS_ValueToNumber(IntPtr cx, ulong v, out double dp);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr JS_CompileFile(IntPtr cx, IntPtr obj, string filename);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern int JS_ExecuteScript(IntPtr cx, IntPtr obj, IntPtr script, out ulong rval);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr JS_DefineFunction(IntPtr cx, IntPtr obj, string name, JSNative call, int nargs, int flags);
        [DllImport(SPIDERMONKEY, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr JS_NewStringCopyN(IntPtr cx, string s, int n);

        [DllImport("C++Test.exe", CallingConvention = CallingConvention.Cdecl)]
        public static extern void _TEST_(IntPtr ptr);
    }
}
